﻿using AutoMapper;
using QYmall.Core.API.Filters;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper.Internal;
using System.Dynamic;

namespace QYmall.Core.API.Controllers
{
    /// <summary>
    /// 商城类别
    /// </summary>
    [Route("admin/shop/category")]
    [ApiController]
    public class ShopCategoryController : ControllerBase
    {
        private readonly IMerchantService _merchantService;
        private readonly IShopCategoryService _shopCategoryService;
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        public ShopCategoryController(IMerchantService merchantService, IShopCategoryService shopCategoryService, IUserService userService, IMapper mapper)
        {
            _merchantService = merchantService;
            _shopCategoryService = shopCategoryService;
            _userService = userService;
            _mapper = mapper;
        }

        #region 管理员调用接口==========================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/admin/shop/category/1
        /// </summary>
        [HttpGet("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.View)]
        public async Task<IActionResult> GetById([FromRoute] int id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            //使用AutoMapper转换成ViewModel
            //根据字段进行塑形
            var result = _mapper.Map<ShopCategoryDto>(model).ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/admin/shop/category/view/1/0
        /// </summary>
        [HttpGet("view/{parentId}/{top}")]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.View)]
        public async Task<IActionResult> GetList([FromRoute] int parentId, [FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            //检测参数是否合法
            if (!searchParam.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取数据库列表
            var resultFrom = await _shopCategoryService.QueryListAsync(top, parentId, -1);
            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopCategoryDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取树目录列表
        /// 示例：/admin/shop/category
        /// </summary>
        [HttpGet]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.View)]
        public async Task<IActionResult> GetList([FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //如果有查询关健字
            int parentId = 0; //父节点ID
            if (param.Keyword.IsNotNullOrWhiteSpace())
            {
                var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Title != null && x.Title.Contains(param.Keyword));
                if (model == null)
                {
                    return NotFound(ResponseMessage.Error("暂无查询记录"));
                }
                parentId = model.Id;
            }
            //获取数据库列表
            var resultFrom = await _shopCategoryService.QueryListAsync(parentId, -1);
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var resultDto = resultFrom.AsEnumerable().ShapeData(param.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/admin/shop/category
        /// </summary>
        [HttpPost]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.Add)]
        public async Task<IActionResult> Add([FromBody] ShopCategoryEditDto modelDto)
        {
            //映射成实体
            var model = _mapper.Map<ShopCategory>(modelDto);
            //获取当前用户名
            model.AddBy = await _userService.GetUserNameAsync();
            model.AddTime = DateTime.Now;
            //写入数据库
            var mapModel = await _shopCategoryService.AddAsync(model);
            //映射成DTO再返回，否则出错
            var result = _mapper.Map<ShopCategoryDto>(mapModel);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/admin/shop/category/1
        /// </summary>
        [HttpPut("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] int id, [FromBody] ShopCategoryEditDto modelDto)
        {
            //查找记录
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            //获取当前用户名
            model.UpdateBy = await _userService.GetUserNameAsync();
            model.UpdateTime = DateTime.Now;

            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelDto, model);
            var result = await _shopCategoryService.SaveAsync();
            return NoContent();
        }

        /// <summary>
        /// 局部更新一条记录
        /// 示例：/admin/shop/category/1
        /// Body：[{"op":"replace","path":"/title","value":"new title"}]
        /// </summary>
        [HttpPatch("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.Edit)]
        public async Task<IActionResult> Update([FromRoute] int id, [FromBody] JsonPatchDocument<ShopCategoryEditDto> patchDocument)
        {
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }

            var modelToPatch = _mapper.Map<ShopCategoryEditDto>(model);
            patchDocument.ApplyTo(modelToPatch, ModelState);
            //验证数据是否合法
            if (!TryValidateModel(modelToPatch))
            {
                return ValidationProblem(ModelState);
            }
            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelToPatch, model);
            await _shopCategoryService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/admin/shop/category/1
        /// </summary>
        [HttpDelete("{id}")]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.Delete)]
        public async Task<IActionResult> Delete([FromRoute] int id)
        {
            if (!await _shopCategoryService.ExistsAsync<ShopCategory>(x => x.Id == id))
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            var result = await _shopCategoryService.DeleteAsync(x => x.Id == id);

            return NoContent();
        }

        /// <summary>
        /// 批量删除记录(级联数据)
        /// 示例：/admin/shop/category?ids=1,2,3
        /// </summary>
        [HttpDelete]
        [Authorize]
        [AuthorizeFilter("ShopCategory", ActionType.Delete)]
        public async Task<IActionResult> DeleteByIds([FromQuery] string Ids)
        {
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var arrIds = Ids.ToIEnumerable<int>();
            if (arrIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _shopCategoryService.DeleteAsync(x => arrIds.Contains(x.Id));

            return NoContent();
        }
        #endregion

        #region 商户管理调用============================
        /// <summary>
        /// 获取树目录列表
        /// 示例：/merchant/shop/category
        /// </summary>
        [HttpGet("/merchant/shop/category")]
        [Authorize]
        public async Task<IActionResult> MerchantGetList([FromQuery] BaseParameter param)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //如果有查询关健字
            int parentId = 0; //父节点ID
            if (param.Keyword.IsNotNullOrWhiteSpace())
            {
                var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.MerchantId == merchant.Id && x.Title != null && x.Title.Contains(param.Keyword));
                if (model == null)
                {
                    return NotFound(ResponseMessage.Error("暂无查询记录"));
                }
                parentId = model.Id;

                var result = _mapper.Map<ShopCategoryDto>(model);

                //获取数据库列表
                var resultFrom = await _shopCategoryService.QueryListByMerchantIdAsync(merchant.Id, parentId, -1);

                if (resultFrom != null)
                {
                    result.Children = resultFrom.ToList();
                }

                var resultDto = new[] { result };
                return Ok(resultDto);
            }
            else
            {
                //获取数据库列表
                var resultFrom = await _shopCategoryService.QueryListByMerchantIdAsync(merchant.Id, parentId, -1);
                //使用AutoMapper转换成ViewModel，根据字段进行塑形
                var resultDto = resultFrom.AsEnumerable().ShapeData(param.Fields);
                return Ok(resultDto);
            }
        }

        /// <summary>
        /// 根据ID获取数据
        /// 示例：/merchant/shop/category/1
        /// </summary>
        [HttpGet("/merchant/shop/category/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantGetById([FromRoute] int id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            //使用AutoMapper转换成ViewModel
            //根据字段进行塑形
            var result = _mapper.Map<ShopCategoryDto>(model).ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/merchant/shop/category
        /// </summary>
        [HttpPost("/merchant/shop/category")]
        [Authorize]
        public async Task<IActionResult> MerchantAdd([FromBody] ShopCategoryEditDto modelDto)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            //映射成实体
            var model = _mapper.Map<ShopCategory>(modelDto);
            modelDto.MerchantId = merchant.Id;
            //获取当前用户名
            model.AddBy = await _userService.GetUserNameAsync();
            model.AddTime = DateTime.Now;
            //写入数据库
            var mapModel = await _shopCategoryService.AddAsync(model);
            //映射成DTO再返回，否则出错
            var result = _mapper.Map<ShopCategoryDto>(mapModel);
            return Ok(result);
        }

        /// <summary>
        /// 修改一条记录
        /// 示例：/merchant/shop/category/1
        /// </summary>
        [HttpPut("/merchant/shop/category/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantUpdate([FromRoute] int id, [FromBody] ShopCategoryEditDto modelDto)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            //查找记录
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            modelDto.MerchantId = merchant.Id;
            //获取当前用户名
            model.UpdateBy = await _userService.GetUserNameAsync();
            model.UpdateTime = DateTime.Now;

            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelDto, model);
            var result = await _shopCategoryService.SaveAsync();
            return NoContent();
        }

        /// <summary>
        /// 局部更新一条记录
        /// 示例：/merchant/shop/category/1
        /// Body：[{"op":"replace","path":"/title","value":"new title"}]
        /// </summary>
        [HttpPatch("/merchant/shop/category/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantUpdate([FromRoute] int id, [FromBody] JsonPatchDocument<ShopCategoryEditDto> patchDocument)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => x.Id == id, WriteRoRead.Write);
            if (model == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            model.MerchantId = merchant.Id;
            var modelToPatch = _mapper.Map<ShopCategoryEditDto>(model);
            patchDocument.ApplyTo(modelToPatch, ModelState);
            //验证数据是否合法
            if (!TryValidateModel(modelToPatch))
            {
                return ValidationProblem(ModelState);
            }
            //更新操作AutoMapper替我们完成，只需要调用保存即可
            _mapper.Map(modelToPatch, model);
            await _shopCategoryService.SaveAsync();

            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/merchant/shop/category/1
        /// </summary>
        [HttpDelete("/merchant/shop/category/{id}")]
        [Authorize]
        public async Task<IActionResult> MerchantDelete([FromRoute] int id)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (!await _shopCategoryService.ExistsAsync<ShopCategory>(x => x.Id == id && x.MerchantId == merchant.Id))
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            var result = await _shopCategoryService.DeleteAsync(x => x.Id == id);

            return NoContent();
        }

        /// <summary>
        /// 批量删除记录(级联数据)
        /// 示例：/merchant/shop/category?ids=1,2,3
        /// </summary>
        [HttpDelete("/merchant/shop/category")]
        [Authorize]
        public async Task<IActionResult> MerchantDeleteByIds([FromQuery] string Ids)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var arrIds = Ids.ToIEnumerable<int>();
            if (arrIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _shopCategoryService.DeleteAsync(x => arrIds.Contains(x.Id) && x.MerchantId == merchant.Id);

            return NoContent();
        }
        /// <summary>
        /// 获取指定数量列表
        /// 示例：/admin/shop/category/view/1/0
        /// </summary>
        [HttpGet("/merchant/shop/category/view/{parentId}/{top}")]
        [Authorize]
        public async Task<IActionResult> MerchantGetList([FromRoute] int parentId, [FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            var UserId = await _userService.GetUserIdAsync();
            var merchant = await _merchantService.QueryAsync<Merchants>(x => x.UserId == UserId, WriteRoRead.Write);
            if (merchant == null)
            {
                return Unauthorized(ResponseMessage.Error("尚未开通商户功能，请检查重试"));
            }
            //检测参数是否合法
            if (!searchParam.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取数据库列表
            var resultFrom = await _shopCategoryService.QueryListByMerchantIdAsync(top, parentId, -1);
            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopCategoryDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        #endregion

        #region 前台调用接口============================
        /// <summary>
        /// 根据ID获取数据
        /// 示例：/client/shop/category/1
        /// </summary>
        [HttpGet("/client/shop/category/{id}")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetById([FromRoute] int id, [FromQuery] BaseParameter param)
        {
            return await GetById(id, param);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/client/shop/category/view/1/0
        /// </summary>
        [HttpGet("/client/shop/category/view/{parentId}/{top}")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetList([FromRoute] int parentId, [FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            //检测参数是否合法
            if (!searchParam.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取数据库列表
            var resultFrom = await _shopCategoryService.QueryListAsync(top, parentId, 0);
            //映射成DTO，根据字段进行塑形
            var resultDto = _mapper.Map<IEnumerable<ShopCategoryDto>>(resultFrom).ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取树目录列表
        /// 示例：/client/shop/category
        /// </summary>
        [HttpGet("/client/shop/category")]
        [CachingFilter]
        public async Task<IActionResult> ClientGetList([FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<ShopCategoryDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //如果有查询关健字
            int parentId = 0; //父节点ID
            if (param.Keyword.IsNotNullOrWhiteSpace())
            {
                var model = await _shopCategoryService.QueryAsync<ShopCategory>(x => (x.Title != null && x.Title.Contains(param.Keyword)));
                if (model == null)
                {
                    return NotFound(ResponseMessage.Error("暂无查询记录"));
                }
                parentId = model.Id;
            }
            //获取数据库列表
            var resultFrom = await _shopCategoryService.QueryListAsync(parentId, 0);
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var resultDto = resultFrom.AsEnumerable().ShapeData(param.Fields);
            //返回成功200
            return Ok(resultDto);
        }
        #endregion

    }
}
